package com.sentiment.obj;

import org.apache.log4j.Logger;
import org.bson.Document;

import com.sentiment.config.Config;
import com.sentiment.tools.StringTools;

public class Text {
	// 构造函数
	public Text() {
	}

	public Text(String title, String content) {
		super();
		this.title = title;
		setContent(content);
		this.id = "null";
		this.writer = "null";
		this.publishTime = "null";
	}

	public Text(String title, String content,  String id, String writer,String publishTime) {
		super();
		this.title = title;
		// setContent里面设置了charsAmount paraAmount stnAmount属性
		setContent(content);
		this.id = id;
		this.writer = writer;
		this.publishTime = publishTime;
	}
	
	public Text(Document doc){
		this.title = doc.getString("title");
		Document content = (Document) doc.get("content");
		this.content = content;
		this.id = doc.getString("id");
		this.writer = doc.getString("writer");
		this.publishTime = doc.getString("publishTime");
		
		setStnAmount(content.getInteger("stnAmount"));
		setParaAmount(content.getInteger("paraAmount"));
		setCharsAmount(content.getInteger("charsAmount"));
	}
	/**
	 * key:publishTime val:页面的发布时间 有些页面可能没有该内容
	 */
	private String publishTime = "null";
	public String getPublishTime() {
		return publishTime;
	}

	public void setPublishTime(String publishTime) {
		this.publishTime = publishTime;
	}
	/**
	 * 文章作者（暂缺
	 */
	private String writer = "null";
	/**
	 * 用户输入的标题
	 */
	private String title = "null";
	/**
	 * 用户输入的文本段 已按句和段拆分 Document 中是句和文本内容对应
	 */
	private Document content = null;
	/**
	 * 段落数
	 */
	private Integer paraAmount = 0;
	/**
	 * 该字段记录是用户输入的文本还是爬取的文本 0代表用户输入 1代表爬取的
	 */
	private Integer source = -1;
	/**
	 * 句子总数（高一级的总数 代表所有段落中的总和
	 */
	private Integer stnAmount = 0;
	/**
	 * 自动生成的id 用于索引该文章（未实现
	 */
	private String id = "null";
	/**
	 * 文章总字数
	 */
	private Integer charsAmount = 0;

	public Integer getCharsAmount() {
		return charsAmount;
	}

	public void setCharsAmount(Integer charsAmount) {
		this.charsAmount = charsAmount;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Integer getStnAmount() {
		return stnAmount;
	}

	public void setStnAmount(Integer stnAmount) {
		this.stnAmount = stnAmount;
	}

	public Integer getSource() {
		return source;
	}

	public void setSource(Integer source) {
		this.source = source;
	}

	public Integer getParaAmount() {
		return paraAmount;
	}

	public void setParaAmount(Integer paraAmount) {
		this.paraAmount = paraAmount;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
	
	public Document getContent() {
		return content;
	}

	private void setContent(String content) {
		this.content = contentParser(content);
	}

	public void setContent(Document content) {
		this.content = content;
	}
	public String getContent(int paraNum){
		if(content != null && content.getInteger("paraAmount")>=paraNum ){
			Document para = (Document)content.get(String.valueOf(paraNum));
			int stnAmount = para.getInteger("stnAmount");
			StringBuilder sb = new StringBuilder();
			for(int i = 1 ; i <= stnAmount ;i++){
				sb.append(((Document)para.get(String.valueOf(i))).getString("text"));
			}
			return sb.toString();
		}
		return null;
	}
	/**
	 * 根据段落号和句子号获取句子
	 * @param paraNum
	 * @param stnNum
	 * @return
	 */
	public String getContent(int paraNum,int stnNum){
		if(content != null && content.getInteger("paraAmount")>=paraNum && ((Document)content.get(String.valueOf(paraNum))).getInteger("stnAmount")>=stnNum){
			return ((Document)((Document)content.get(String.valueOf(paraNum))).get(String.valueOf(stnNum))).getString("text");
		}
		return null;
	}
	private Logger logger = Config.getLogger(this.getClass());

	/**
	 * 解析用户输入的正文文本
	 * 
	 * @param s
	 *            文本内容
	 * @return 返回Document对象
	 */
	private Document contentParser(String s) {
		Document content = new Document();
		// 将半角字符替换成全角字符
		s = StringTools.replacePunct(s);
		s = StringTools.deleteNbsp(s);
		// 按换行切割
		String[] split = s.split("\n");
		logger.info("-----切割后的文本段分别为-----");
		for (int i = 0; i < split.length; i++) {
			logger.info(split[i]);
		}
		paraAmount = split.length;
		for (int i = 0; i < split.length; i++) {
			Document para = stringSplit(split[i]);
			// 将段落添加到doc中
			content.append(Integer.toString(i + 1), para);
		}
		content.append("paraAmount", paraAmount);
		content.append("stnAmount", stnAmount);
		content.append("charsAmount", charsAmount);
		return content;
	}

	/**
	 * 对字符串按句进行分割
	 * 
	 * @param str
	 *            传入的字符串
	 * @return 分割后的字符串Document key（每一句的句号）：val（每一句的文本），包含有分隔符
	 */
	private Document stringSplit(String str) {
		Document para = new Document();
		// temp用于存储首、中分隔符、尾
		String temp[] = new String[3];
		String src = str;
		int sentence = 0;
		int charsInStn = 0;
		int charsInPara = 0;
		do {
			temp = findFirstSeparator(src);
			// 如果首句不为空 则将它添加到到Document中
			if (temp[0] != null && !temp[0].isEmpty()) {
				sentence++;
				// 如果句子有结尾字符则按默认添加 否则添加一个。作为结尾字符
				String text = ((temp[1] == null) ? (temp[0]+"。") : (temp[0] + temp[1]));

				charsInStn = text.length();
				charsInPara += charsInStn;
				Document stn = new Document("text", text).append("charsAmount", charsInStn);
				para.append(Integer.toString(sentence), stn);
			}
			src = temp[2];
		} while (src != null);
		stnAmount += sentence;
		charsAmount += charsInPara;
		// 将句子总数记录到Document
		para.append("stnAmount", sentence);
		para.append("charsAmount", charsInPara);
		return para;
	}
	/**
	 * 找出一段文本中的第一个分隔符所在位置
	 * 
	 * @param str
	 *            待查找的文本
	 * @return 返回一个大小为3的String数组，0存储分隔符之前的文本，1存储分割符，2存储分隔符之后的文本
	 */
	private String[] findFirstSeparator(String str) {
		String temp[] = new String[3];
		// 初始化
		for (int i = 0; i != 3; i++) {
			temp[i] = null;
		}
		for (int i = 0; i != str.length(); i++) {
			switch (str.charAt(i)) {
			//点不分句 不然代码中会出现很多不必要的分句
//			case '.':
			case '。':
			case '！':
			case '？':
			case '；':
				temp[0] = str.substring(0, i).trim();
				temp[1] = Character.toString(str.charAt(i));
				if ((i + 1) == str.length())
					temp[2] = null;
				else
					temp[2] = str.substring(i + 1).trim();
				return temp;
			}
		}
		temp[0] = str.trim();

		return temp;
	}
	/**
	 * 将Document中的内容转为字符串内容供算法处理
	 */
	public static String content2String(Document content){
		StringBuilder sb = new StringBuilder();
		int paraAmount = content.getInteger("paraAmount");
		for(int para = 1 ; para <= paraAmount ;para++){
			Document paraContent = (Document)content.get(String.valueOf(para));
			int stnAmount = paraContent.getInteger("stnAmount");
			for(int stn = 1 ; stn <=stnAmount ; stn++){
				sb.append(((Document)paraContent.get(String.valueOf(stn))).getString("text"));
			}
			sb.append("\n");
		}
		return sb.toString();
	}
}
